/*
 * @Copyright: All rights reserved. Please Contact the Email sagittar_zhang@126.com
 */

package cn.guet.base.spider.http;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

import lombok.Getter;
import lombok.Setter;

/**
 * 代理基类
 *
 * @author SAGITTAR
 */
@Getter
@Setter
public class Proxy implements Delayed, Serializable {
    private static final long serialVersionUID = -7583883432417635332L;

    /**
     * 任务间隔时间，单位毫秒
     */
    private long timeInterval;
    private String ip;
    private int port;
    private boolean availableFlag;
    private boolean anonymousFlag;
    /**
     * 最近一次请求成功时间
     */
    private long lastSuccessfulTime;
    // 请求成功总耗时
    /**
     * 请求成功总耗时
     */
    private long successfulTotalTime;
    /**
     * 请求失败次数
     */
    private int failureTimes;
    /**
     * 请求成功次数
     */
    private int successfulTimes;
    /**
     * 成功请求平均耗时
     */
    private double successfulAverageTime;

    public Proxy(String ip, int port, long timeInterval) {
        this.ip = ip;
        this.port = port;
        this.timeInterval = timeInterval;
        this.timeInterval = TimeUnit.NANOSECONDS.convert(timeInterval, TimeUnit.MILLISECONDS) + System.nanoTime();
    }

    public void setTimeInterval(long timeInterval) {
        this.timeInterval = TimeUnit.NANOSECONDS.convert(timeInterval, TimeUnit.MILLISECONDS) + System.nanoTime();
    }

    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(timeInterval - System.nanoTime(), TimeUnit.NANOSECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        Proxy element = (Proxy) o;
        if (successfulAverageTime == 0 || element.successfulAverageTime == 0) {
            return 0;
        }
        if (successfulAverageTime > element.successfulAverageTime) {
            return 1;
        }
        return -1;
    }

    @Override
    public String toString() {
        Map<String, Object> result = new HashMap<>(10, 1);
        result.put("timeInterval", timeInterval);
        result.put("ip", ip);
        result.put("port", port);
        result.put("availableFlag", availableFlag);
        result.put("anonymousFlag", anonymousFlag);
        result.put("lastSuccessfulTime", lastSuccessfulTime);
        result.put("successfulTotalTime", successfulTotalTime);
        result.put("failureTimes", failureTimes);
        result.put("successfulTimes", successfulTimes);
        result.put("successfulAverageTime", successfulAverageTime);
        return result.toString();
    }

    public String getProxyStr() {
        return ip + ":" + port;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (Objects.isNull(obj)) {
            return false;
        }
        if (getClass() == obj.getClass()) {
            Proxy proxy = (Proxy) obj;
            return port == proxy.port && StringUtils.equals(ip, proxy.ip);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return ip.hashCode() * 31 + port;
    }
}
